package com.blate.dogxiao.adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.databinding.ViewDataBinding;

/**
 * @author Az
 * on 2020/10/20
 */
public abstract class SimpleRecyclerViewAdapter<VB extends ViewDataBinding>
        extends ViewBindingRecyclerViewAdapter<VB> {

    private MonitorViewCollector<VB> mMonitorViewCollector;
    private OnItemChildClickListener mOnItemChildClickListener;

    @NonNull
    @Override
    public SimpleHolder<VB> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        VB binding = onCreateBinding(LayoutInflater.from(parent.getContext()), parent, viewType);
        SimpleHolder<VB> holder = new SimpleHolder<>(binding);
        holder.setOnItemChildClickListener(mOnItemChildClickListener);
        if (mMonitorViewCollector != null) {
            mMonitorViewCollector.collectorMonitorView(binding, holder);
        }
        return holder;
    }

    /**
     * 设置条目点击监听
     *
     * @param collector 收集器,收集需要监听的视图
     * @param listener  监听器,被收集视图的响应事件触发后会回调到该方法
     */
    public void setItemChildClickListener(MonitorViewCollector<VB> collector, OnItemChildClickListener listener) {
        this.mMonitorViewCollector = collector;
        this.mOnItemChildClickListener = listener;
    }

    /**
     * 条目视图监听器
     * 一个View的点击事件能被监听前提:
     * 调用{@link #setItemChildClickListener(MonitorViewCollector, OnItemChildClickListener)}时
     * 在MonitorViewCollector中调用了{@link MonitorViewCollector#collectorMonitorView(Object, ItemViewMonitor)}中
     * 收集了视图.而且在{@link ItemViewMonitor#monitorView(View)}中监视了View的点击事件,在点击事件触发时回
     * 调了此方法
     */
    public interface OnItemChildClickListener {

        /**
         * 点击事件回调
         *
         * @param view     view被点击了
         * @param position 这个view位于适配器中的position
         */
        void onItemChildClick(View view, int position);

    }

    /**
     * 这个接口用收集需要监视的View
     * View应该存在于{@link SimpleHolder#getBinding()} ()}中
     *
     * @param <VB> 从 VB 中收集监视视图
     */
    interface MonitorViewCollector<VB> {

        /**
         * 收集需要监视的视图
         *
         * @param binding         binding
         * @param itemViewMonitor view监视器
         */
        void collectorMonitorView(VB binding, ItemViewMonitor itemViewMonitor);

    }

    /**
     * View监视器
     */
    interface ItemViewMonitor {

        /**
         * 调用这个方法监视一个视图.
         * 根据实现类不同可以监听View的不同的事件(ex : 点击,长按...)
         *
         * @param view 被监视的View
         */
        void monitorView(View view);

    }

    public static class SimpleHolder<VB extends ViewDataBinding>
            extends ViewBindingHolder<VB>
            implements ItemViewMonitor, View.OnClickListener {

        private OnItemChildClickListener mOnItemChildClickListener;

        public SimpleHolder(@NonNull VB binding) {
            super(binding);
        }

        void setOnItemChildClickListener(OnItemChildClickListener listener) {
            this.mOnItemChildClickListener = listener;
        }

        @Override
        public void onClick(View v) {
            if (mOnItemChildClickListener != null) {
                mOnItemChildClickListener.onItemChildClick(v, getAdapterPosition());
            }
        }

        /**
         * 监视了View的点击事件,在这里事件由{@link #mOnItemChildClickListener}分发
         *
         * @param view 被监视的View
         */
        @Override
        public void monitorView(View view) {
            view.setOnClickListener(this);
        }

    }

}
